/*
dmd nonstd/traits nonstd/typecons -run test
--------------------
X
43CE60
3.1416
0
core.exception.AssertError@nonstd\typecons.d(328): Base.foo() is not implemented
core.exception.AssertError@nonstd\typecons.d(321): Base.foo(lazy int) is not implemented
core.exception.AssertError@nonstd\typecons.d(335): Base.baz(int[]) is not implemented
*/

import std.stdio;
import std.contracts;
import core.exception;

import std.typetuple;
import nonstd.typecons;
import nonstd.traits;


// For covariant return types
interface X {}
interface Y : X {}


interface Ia { X foo() nothrow; }
interface Ib { Y foo() const; }

class Base : Ia, Ib
{
    abstract ref int foo(lazy int);

    // overloading *is* desired (cf. "Hijacking")
    alias Ia.foo foo;
    alias Ib.foo foo;

    // non-abstract function
    real bar() { return 3.1416; }

    // variadic function
    abstract int baz(int[] a...) const nothrow;
}

void main()
{
    auto bh = new BlackHole!Base;
    writeln( bh.foo());
    writeln(&bh.foo((assert(0), 1)));
    writeln( bh.bar());
    writeln( bh.baz(1, 2, 3, 4));

    auto wh = new WhiteHole!Base;
    try { wh.foo();  } catch (AssertError e) { writeln(e); }
    try { wh.foo(1); } catch (AssertError e) { writeln(e); }
    wh.bar(); // Base.bar() is not overridden
    try { wh.baz(1); } catch (AssertError e) { writeln(e); }
}


